﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Navigation;
using Microsoft.SharePoint.Publishing;

using SPBusiness.ExtensionMethods;

namespace SPBusiness
{
   public sealed class Web
   {
      /// <summary>
      /// Web class has only Static Methods, no constructor needed.
      /// </summary>
      private Web() { }

      public static void SetupMasterPageAndCSS(string pSiteUrl, string pWebRelativeUrl, string master, string css, string logo, string logodesc, string title)
      {
         try
         {
            //SPSecurity.RunWithElevatedPrivileges(delegate()
//{
   using (SPSite vSPSite = new SPSite(pSiteUrl))
   {
      using (SPWeb vSPWeb = vSPSite.OpenWeb(pWebRelativeUrl))
      {
         PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(vSPWeb);

         string vSiteUrl = pWebRelativeUrl.EndsWith("/") ? pWebRelativeUrl : pWebRelativeUrl + "/";

         publishingWeb.Web.AlternateCssUrl = vSiteUrl + "Style%20Library/" + css;
         publishingWeb.Web.AllProperties["__InheritsCustomMasterUrl"] = 0;
         publishingWeb.Web.AllProperties["__InheritsMasterUrl"] = 0;
         publishingWeb.Web.CustomMasterUrl = vSiteUrl + "_catalogs/masterpage/" + master;
         publishingWeb.Web.MasterUrl = vSiteUrl + "_catalogs/masterpage/" + master;
         publishingWeb.Title = title;
         publishingWeb.Web.SiteLogoUrl = vSiteUrl + "Style%20Library/images/" + logo;
         publishingWeb.Web.SiteLogoDescription = logodesc;
         publishingWeb.Update();
         publishingWeb.Web.Update();
      }
   }
//});
         }
         catch (Exception ex)
         {
            Logging.LogMessase(typeof(Web).Namespace, typeof(Web).Name, "SetupMasterPageAndCSS", ex);
            throw;
         }

      }

      public static void InheritsMasterPageAndCSS(string pSiteUrl, string pWebRelativeUrl)
      {
         try
         {
            //SPSecurity.RunWithElevatedPrivileges(delegate()
//{
   using (SPSite vSPSite = new SPSite(pSiteUrl))
   {
      using (SPWeb vSPWeb = vSPSite.OpenWeb(pWebRelativeUrl))
      {
         if (!vSPWeb.IsRootWeb)
         {
            PublishingWeb vPublishingWeb = PublishingWeb.GetPublishingWeb(vSPWeb);
            PublishingWeb vPublishingWebRoot = PublishingWeb.GetPublishingWeb(vSPWeb.Site.RootWeb);

            vPublishingWeb.AlternateCssUrl.SetValue(vPublishingWebRoot.AlternateCssUrl.Value);
            vPublishingWeb.CustomMasterUrl.SetValue(vPublishingWebRoot.CustomMasterUrl.Value);
            vPublishingWeb.MasterUrl.SetValue(vPublishingWebRoot.MasterUrl.Value);

            vPublishingWeb.Web.Update();
            vPublishingWeb.Update();

            vPublishingWeb.AlternateCssUrl.SetInherit(true, true);
            vPublishingWeb.CustomMasterUrl.SetInherit(true, true);
            vPublishingWeb.MasterUrl.SetInherit(true, true);

            vPublishingWeb.Web.Update();
            vPublishingWeb.Update();

         }
      }
   }
//});
         }
         catch (Exception ex)
         {
            Logging.LogMessase(typeof(Web).Namespace, typeof(Web).Name, "InheritsMasterPageAndCSS", ex);
            throw;
         }

      }

      public static void SetDefaultPageLayout(string pSiteUrl, string pWebRelativeUrl, string pPageLayoutName)
      {
         try
         {
            //SPSecurity.RunWithElevatedPrivileges(delegate()
//{
   using (SPSite vSPSite = new SPSite(pSiteUrl))
   {
      using (SPWeb vSPWeb = vSPSite.OpenWeb(pWebRelativeUrl))
      {
         PublishingWeb vPublishingWeb = PublishingWeb.GetPublishingWeb(vSPWeb);

         PageLayout[] vPageLayouts = vPublishingWeb.GetAvailablePageLayouts();

         PageLayout vPageLayout = vPageLayouts.OfType<PageLayout>().Where(x => x.Name == pPageLayoutName).FirstOrDefault();

         if (vPageLayout != null && (vPublishingWeb.DefaultPageLayout == null || vPublishingWeb.DefaultPageLayout != vPageLayout))
         {
            vPublishingWeb.SetDefaultPageLayout(vPageLayout, true);
            vPublishingWeb.Update();
            vPublishingWeb.Web.Update();
         }
      }
   }
//});
         }
         catch (Exception ex)
         {
            Logging.LogMessase(typeof(Web).Namespace, typeof(Web).Name, "SetDefaultPageLayout", ex);
            throw;
         }

      }

      public static void RevertMasterPageAndCss(string pSiteUrl, string pWebRelativeUrl, string pWelcomePageURL)
      {
         try
         {
            //SPSecurity.RunWithElevatedPrivileges(delegate()
//{
   using (SPSite vSPSite = new SPSite(pSiteUrl))
   {
      using (SPWeb vSPWeb = vSPSite.OpenWeb(pWebRelativeUrl))
      {
         vSPWeb.CustomMasterUrl = "/_catalogs/masterpage/v4.master";
         vSPWeb.MasterUrl = "/_catalogs/masterpage/v4.master";
         vSPWeb.Update();

         SPFolder rootFolder = vSPWeb.RootFolder;
         rootFolder.WelcomePage = pWelcomePageURL;
         rootFolder.Update();

         vSPWeb.Update();
      }
   }
//});
         }
         catch (Exception ex)
         {
            Logging.LogMessase(typeof(Web).Namespace, typeof(Web).Name, "SetDefaultPageLayout", ex);
            throw;
         }
      }

      public static void SetSPWebPermission(string pSiteUrl, string pWebRelativeUrl, string pGroupName, SPRoleType pSPRoleType)
      {
         try
         {
            //SPSecurity.RunWithElevatedPrivileges(delegate()
            //{
               using (SPSite vSPSite = new SPSite(pSiteUrl))
               {
                  using (SPWeb vSPWeb = vSPSite.OpenWeb(pWebRelativeUrl))
                  {

                     SPGroup vSPGroup = vSPWeb.SiteGroups[pGroupName];

                     if (vSPWeb != null)
                     {
                        if (!vSPWeb.HasUniqueRoleAssignments)
                        {
                           vSPWeb.BreakRoleInheritance(true, true);
                        }

                        SPRoleAssignment vSPRoleAssignment = null;
                        SPRoleDefinition vSPRoleDefinition = null;

                        SPRoleDefinition vSPRoleDefinitionToAdd = vSPWeb.RoleDefinitions.GetByType(pSPRoleType);

                        bool vFound = false;

                        for (int k = vSPWeb.RoleAssignments.Count - 1; k >= 0; k--)
                        {
                           vSPRoleAssignment = vSPWeb.RoleAssignments[k];

                           if (vSPRoleAssignment.Member.ID == vSPGroup.ID)
                           {
                              for (int i = vSPRoleAssignment.RoleDefinitionBindings.Count - 1; i >= 0; i--)
                              {
                                 vSPRoleDefinition = vSPRoleAssignment.RoleDefinitionBindings[i];
                                 if (vSPRoleDefinition.Name != vSPRoleDefinitionToAdd.Name)
                                 {
                                    vSPRoleAssignment.RoleDefinitionBindings.Remove(i);
                                    vSPRoleAssignment.Update();
                                 }
                                 else
                                 {
                                    vFound = true;
                                 }
                              }
                              if (vSPRoleAssignment.RoleDefinitionBindings.Count == 0)
                              {
                                 vSPWeb.RoleAssignments.Remove(k);
                                 vSPWeb.Update();
                              }
                           }
                        }

                        if (!vFound)
                        {
                           vSPRoleAssignment = new SPRoleAssignment(vSPGroup);

                           vSPRoleAssignment.RoleDefinitionBindings.Add(vSPRoleDefinitionToAdd);

                           vSPWeb.RoleAssignments.Add(vSPRoleAssignment);

                           vSPWeb.Update();
                        }
                     }
                  }
               }
            //});
         }
         catch (Exception ex)
         {
            Logging.LogMessase(typeof(Web).Namespace, typeof(Web).Name, "SetSPWebPermission", ex);
            throw;
         }

      }

      public static void SetSPWebPermission(string pSiteUrl, string pWebRelativeUrl, string pGroupName, string pRole)
      {
         try
         {
            //SPSecurity.RunWithElevatedPrivileges(delegate()
            //{
               using (SPSite vSPSite = new SPSite(pSiteUrl))
               {
                  using (SPWeb vSPWeb = vSPSite.OpenWeb(pWebRelativeUrl))
                  {
                     SPGroup vSPGroup = vSPWeb.SiteGroups[pGroupName];

                     if (vSPWeb != null)
                     {
                        if (!vSPWeb.HasUniqueRoleAssignments)
                        {
                           vSPWeb.BreakRoleInheritance(true, true);
                        }

                        SPRoleAssignment vSPRoleAssignment = null;
                        SPRoleDefinition vSPRoleDefinition = null;

                        SPRoleDefinition vSPRoleDefinitionToAdd = vSPWeb.RoleDefinitions[pRole];

                        bool vFound = false;

                        for (int k = vSPWeb.RoleAssignments.Count - 1; k >= 0; k--)
                        {
                           vSPRoleAssignment = vSPWeb.RoleAssignments[k];

                           if (vSPRoleAssignment.Member.ID == vSPGroup.ID)
                           {
                              for (int i = vSPRoleAssignment.RoleDefinitionBindings.Count - 1; i >= 0; i--)
                              {
                                 vSPRoleDefinition = vSPRoleAssignment.RoleDefinitionBindings[i];
                                 if (vSPRoleDefinition.Name != vSPRoleDefinitionToAdd.Name)
                                 {
                                    vSPRoleAssignment.RoleDefinitionBindings.Remove(i);
                                    vSPRoleAssignment.Update();
                                 }
                                 else
                                 {
                                    vFound = true;
                                 }
                              }
                              if (vSPRoleAssignment.RoleDefinitionBindings.Count == 0)
                              {
                                 vSPWeb.RoleAssignments.Remove(k);
                                 vSPWeb.Update();
                              }
                           }
                        }

                        if (!vFound)
                        {
                           vSPRoleAssignment = new SPRoleAssignment(vSPGroup);

                           vSPRoleAssignment.RoleDefinitionBindings.Add(vSPRoleDefinitionToAdd);

                           vSPWeb.RoleAssignments.Add(vSPRoleAssignment);

                           vSPWeb.Update();
                        }
                     }
                  }
               }
            //});
         }
         catch (Exception ex)
         {
            Logging.LogMessase(typeof(Web).Namespace, typeof(Web).Name, "SetSPWebPermission", ex);
            throw;
         }

      }

      public static void ConfigureDefaultGroups(string pSiteUrl, string pWebRelativeUrl)
      {
         try
         {
            //SPSecurity.RunWithElevatedPrivileges(delegate()
            //{
               using (SPSite vSPSite = new SPSite(pSiteUrl))
               {
                  using (SPWeb vSPWeb = vSPSite.OpenWeb(pWebRelativeUrl))
                  {
                     string AssociatedVisitorGroupAppName = vSPWeb.Title + "Visitors";
                     string AssociatedOwnerGroupAppName = vSPWeb.Title + "Owners";
                     string AssociatedMemberGroupAppName = vSPWeb.Title + "Members";

                     if ((!DoesGroupExists(pSiteUrl, pWebRelativeUrl, AssociatedVisitorGroupAppName)) && (!DoesGroupExists(pSiteUrl, pWebRelativeUrl, AssociatedOwnerGroupAppName)) && (!DoesGroupExists(pSiteUrl, pWebRelativeUrl, AssociatedMemberGroupAppName)))
                     {

                        vSPWeb.AssociatedVisitorGroup = null;
                        vSPWeb.AssociatedMemberGroup = null;
                        vSPWeb.AssociatedOwnerGroup = null;

                        if ((!vSPWeb.IsRootWeb) && (!vSPWeb.HasUniqueRoleAssignments))
                        {
                           vSPWeb.BreakRoleInheritance(true);
                        }
                        vSPWeb.Update();

                        vSPWeb.Properties["vti_associatevisitorgroup"] = vSPWeb.AssociatedVisitorGroup.ID.ToString();
                        vSPWeb.Properties["vti_associateownergroup"] = vSPWeb.AssociatedOwnerGroup.ID.ToString();
                        vSPWeb.Properties["vti_associatemembergroup"] = vSPWeb.AssociatedMemberGroup.ID.ToString();
                        vSPWeb.Properties.Update();
                        vSPWeb.Update();


                     }
                  }
               }
            //});
         }
         catch (Exception ex)
         {
            Logging.LogMessase(typeof(Web).Namespace, typeof(Web).Name, "ConfigureDefaultGroups", ex);
            throw;
         }

      }

      public static bool DoesGroupExists(string pSiteUrl, string pWebRelativeUrl, string pGroupName)
      {
         try
         {
            using (SPSite vSPSite = new SPSite(pSiteUrl))
            {
               using (SPWeb vSPWeb = vSPSite.OpenWeb(pWebRelativeUrl))
               {
                  return vSPWeb.SiteGroups.OfType<SPGroup>().Where(x => x.Name.ToUpper() == pGroupName.ToUpper()).Any();
               }
            }
         }
         catch (Exception ex)
         {
            Logging.LogMessase(typeof(Web).Namespace, typeof(Web).Name, "DoesGroupExists", ex);
            throw;
         }
      }

      public static void PublishAndApproveFilesRecursive(string pSiteUrl, string pWebRelativeUrl)
      {
         try
         {
            //SPSecurity.RunWithElevatedPrivileges(delegate()
            //{
               using (SPSite vSPSite = new SPSite(pSiteUrl))
               {
                  using (SPWeb vSPWeb = vSPSite.OpenWeb(pWebRelativeUrl))
                  {
                     foreach (SPList vSPList in vSPWeb.Lists)
                     {
                        if (vSPList.BaseType == SPBaseType.DocumentLibrary)
                        {
                           if (vSPList.BaseTemplate != SPListTemplateType.MasterPageCatalog || vSPWeb.IsRootWeb)
                           {
                              DocumentLibrary.PublishAndApproveFilesRecursive(vSPList as SPDocumentLibrary);
                           }
                        }
                     }
                  }
               }
            //});
         }
         catch (Exception ex)
         {
            Logging.LogMessase(typeof(Web).Namespace, typeof(Web).Name, "PublishAndApproveFilesRecursive", ex);
            throw;
         }

      }

      public static void RemoveDuplicateWebPartsInForms(string pSiteUrl, string pWebRelativeUrl)
      {
         try
         {
            //SPSecurity.RunWithElevatedPrivileges(delegate()
           // {
               using (SPSite vSPSite = new SPSite(pSiteUrl))
               {
                  using (SPWeb vSPWeb = vSPSite.OpenWeb(pWebRelativeUrl))
                  {
                     foreach (SPList vSPList in vSPWeb.Lists)
                     {
                        if (!System.String.IsNullOrEmpty(vSPList.DefaultDisplayFormUrl))
                        {
                           File.RemoveDuplicateWebParts(vSPWeb.GetFile(vSPList.DefaultDisplayFormUrl));
                        }
                        if (!System.String.IsNullOrEmpty(vSPList.DefaultEditFormUrl))
                        {
                           File.RemoveDuplicateWebParts(vSPWeb.GetFile(vSPList.DefaultEditFormUrl));
                        }
                        if (!System.String.IsNullOrEmpty(vSPList.DefaultNewFormUrl))
                        {
                           File.RemoveDuplicateWebParts(vSPWeb.GetFile(vSPList.DefaultNewFormUrl));
                        }

                     }
                  }
               }
            //});
         }
         catch (Exception ex)
         {
            Logging.LogMessase(typeof(Web).Namespace, typeof(Web).Name, "RemoveDuplicateWebPartsInForms", ex);
            throw;
         }

      }

      public static void CreateHomeOnlyNavigation(string pSiteUrl, string pWebRelativeUrl, string webrelativeurl)
      {
         try
         {
            //SPSecurity.RunWithElevatedPrivileges(delegate()
            //{
               using (SPSite vSPSite = new SPSite(pSiteUrl))
               {
                  using (SPWeb vSPWeb = vSPSite.OpenWeb(pWebRelativeUrl))
                  {
                     #region EMPTYING NAVIGATION

                     SPNavigationNodeCollection quicklaunchNodes = vSPWeb.Navigation.QuickLaunch;
                     for (int i = quicklaunchNodes.Count - 1; i >= 0; i--)
                     {
                        quicklaunchNodes.Delete(quicklaunchNodes[i]);
                     }
                     SPNavigationNodeCollection topNavigationNodes = vSPWeb.Navigation.TopNavigationBar;
                     for (int i = topNavigationNodes.Count - 1; i >= 0; i--)
                     {
                        topNavigationNodes.Delete(topNavigationNodes[i]);
                     }
                     PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(vSPWeb);
                     SPNavigationNodeCollection globalNavigationNodes = publishingWeb.Navigation.GlobalNavigationNodes;

                     for (int i = globalNavigationNodes.Count - 1; i >= 0; i--)
                     {
                        globalNavigationNodes.Delete(globalNavigationNodes[i]);
                     }

                     SPNavigationNodeCollection currentNavigationNodes = publishingWeb.Navigation.CurrentNavigationNodes;
                     for (int i = globalNavigationNodes.Count - 1; i >= 0; i--)
                     {
                        currentNavigationNodes.Delete(currentNavigationNodes[i]);
                     }

                     #endregion


                     Navigation.EmptyNavigation(pSiteUrl, pWebRelativeUrl);

                     #region CREATE GLOBAL NAVIGATION

                     publishingWeb.Navigation.AutomaticSortingMethod = AutomaticSortingMethod.CreatedDate;
                     globalNavigationNodes.Navigation.UseShared = false;
                     publishingWeb.Navigation.CurrentIncludePages = false;
                     publishingWeb.Navigation.CurrentIncludeSubSites = false;
                     publishingWeb.Navigation.GlobalIncludePages = false;
                     publishingWeb.Navigation.GlobalIncludeSubSites = false;

                     SPNavigationNode node = new SPNavigationNode("HOME", webrelativeurl, true);
                     globalNavigationNodes.AddAsLast(node);

                     #endregion
                  }
               }
            //});
         }
         catch (Exception ex)
         {
            Logging.LogMessase(typeof(Web).Namespace, typeof(Web).Name, "createHomeOnlyNavigation", ex);
            throw;
         }

      }

      public static void SetPagePropertiesAndApprove(string pSiteUrl, string pWebRelativeUrl, string oldtitle, string newtitle, string pagedescription)
      {
         try
         {
            //SPSecurity.RunWithElevatedPrivileges(delegate()
            //{
               using (SPSite vSPSite = new SPSite(pSiteUrl))
               {
                  using (SPWeb vSPWeb = vSPSite.OpenWeb(pWebRelativeUrl))
                  {
                     SPList vSPList = vSPWeb.Lists.TryGetList("Pages");
                     if (vSPList != null)
                     {
                        foreach (SPListItem vSPListItem in vSPList.Items)
                        {
                           if (vSPListItem.Url == "Pages/" + oldtitle + ".aspx")
                           {
                              PublishingPage publishingPage = null;
                              if (PublishingPage.IsPublishingPage(vSPListItem))
                              {
                                 publishingPage = PublishingPage.GetPublishingPage(vSPListItem);

                                 File.CheckOut(publishingPage.ListItem.File);

                                 publishingPage.Title = newtitle;
                                 publishingPage.Description = pagedescription;
                                 publishingPage.Contact = publishingPage.Contact;
                                 publishingPage.Update();

                                 File.Approve(publishingPage.ListItem.File);
                              }
                              else
                              {
                                 Logging.LogMessase(typeof(Web).Namespace, typeof(Web).Name, "SetPagePropertiesAndApprove", new System.ArgumentException("This SPListItem is not a PublishingPage"));
                              }
                           }
                        }
                     }
                  }
               }
            //});
         }
         catch (Exception ex)
         {
            Logging.LogMessase(typeof(Web).Namespace, typeof(Web).Name, "SetPagePropertiesAndApprove", ex);
            throw;
         }
      }

      public static void SetWelcomepage(string pSiteUrl, string pWebRelativeUrl, string pWelcomePageURL)
      {
         try
         {
            //SPSecurity.RunWithElevatedPrivileges(delegate()
            //{
               using (SPSite vSPSite = new SPSite(pSiteUrl))
               {
                  using (SPWeb vSPWeb = vSPSite.OpenWeb(pWebRelativeUrl))
                  {
                     SPFolder vSPFolder = vSPWeb.RootFolder;
                     vSPFolder.WelcomePage = pWelcomePageURL;

                     vSPFolder.Update();
                  }
               }
            //});
         }
         catch (Exception ex)
         {
            Logging.LogMessase(typeof(Web).Namespace, typeof(Web).Name, "SetWelcomepage", ex);
            throw;
         }
      }

      public static void ConfigParser(string pSiteUrl, string pWebRelativeUrl, bool pEnabled)
      {
         try
         {
            //SPSecurity.RunWithElevatedPrivileges(delegate()
            //{
               using (SPSite vSPSite = new SPSite(pSiteUrl))
               {
                  using (SPWeb vSPWeb = vSPSite.OpenWeb(pWebRelativeUrl))
                  {
                     if (vSPWeb.ParserEnabled != pEnabled)
                     {
                        vSPWeb.ParserEnabled = pEnabled;
                        vSPWeb.Update();
                     }
                  }
               }
            //});
         }
         catch (Exception ex)
         {
            Logging.LogMessase(typeof(Web).Namespace, typeof(Web).Name, "ConfigParser", ex);
            throw;
         }
      }

      public static void EnableFeature(string pSiteUrl, string pWebRelativeUrl, string pFeatureID, bool pForce, SPFeatureDefinitionScope pSPFeatureDefinitionScope)
      {
         try
         {
            //SPSecurity.RunWithElevatedPrivileges(delegate()
            //{
               using (SPSite vSPSite = new SPSite(pSiteUrl))
               {
                  using (SPWeb vSPWeb = vSPSite.OpenWeb(pWebRelativeUrl))
                  {
                     Guid vFeatureID = new Guid(pFeatureID);

                     if (!vSPWeb.Features.OfType<SPFeature>().Any(x => x.DefinitionId == vFeatureID))
                     {
                        vSPWeb.Features.Add(vFeatureID, pForce, pSPFeatureDefinitionScope);
                        vSPWeb.Update();
                     }
                  }
               }
            //});

         }
         catch (Exception ex)
         {
            Logging.LogMessase(typeof(Web).Namespace, typeof(Web).Name, "EnableFeature", ex);
            throw;
         }
      }

      public static void DisableFeature(string pSiteUrl, string pWebRelativeUrl, string pFeatureID, bool pForce)
      {
         try
         {
            //SPSecurity.RunWithElevatedPrivileges(delegate()
            //{
               using (SPSite vSPSite = new SPSite(pSiteUrl))
               {
                  using (SPWeb vSPWeb = vSPSite.OpenWeb(pWebRelativeUrl))
                  {
                     Guid vFeatureID = new Guid(pFeatureID);

                     if (vSPWeb.Features.OfType<SPFeature>().Any(x => x.DefinitionId == vFeatureID))
                     {
                        vSPWeb.Features.Remove(vFeatureID, pForce);
                        vSPWeb.Update();
                     }
                  }
               }
            //});

         }
         catch (Exception ex)
         {
            Logging.LogMessase(typeof(Web).Namespace, typeof(Web).Name, "DisableFeature", ex);
            throw;
         }
      }
   }
}
